#include "include/SocketIO.hpp"
#include <header.h>
#include <ostream>
#define CAP 1024
int SocketIO::recvPeek(char * buff,int len)const{
    int rep = -1;
    do{
        rep = recv(_fd,buff,len,MSG_PEEK);
    }while(rep == -1 && errno == EINTR);
    return rep;
}

int SocketIO::recvn(char *buff, int len){
    int left = len;
    char * pbuf = buff;
    while(left > 0) {
        int ret = recv(_fd, pbuf, left, 0);
        if(ret == -1 && errno == EINTR) {
            continue;
        } else if (ret == -1) {
            perror("recv");
            return len - left;
        } else if(ret == 0) {
            //代表连接断开了, 但这里不适合
            //做关闭套接字的事儿, 因为该操作是Socket的事儿
            return len - left;
        } else {
            left -= ret;
            pbuf += ret;
        }
    }
    return len - left;
}

int SocketIO::readline(char * buff, int maxlen){
    int recvlen = maxlen -1;
    char * pbuff = buff;
    int total = 0;
    while(recvlen > 0){
        int rflag = recvPeek(pbuff,recvlen);
        if(rflag == -1 && errno == EINTR){
            continue;
        }else if(rflag == -1 || rflag == 0){
            return maxlen - recvlen;
        }else {
        for(int i =0 ;i< rflag; ++i){
            if(buff[total+i] == '\n'){
                recvn(pbuff,i+1);
                buff[total + i] = '\0';
                total += i;
                return total;
            }
        }
        recvn(pbuff,rflag);
        total += rflag;
        recvlen -= rflag;
        pbuff += rflag;
        }
    }
    buff[maxlen-1] = 0;
    return maxlen-1;
}

int SocketIO::sendn(const char *buff,int len){
    const char * pbuff = buff;
    int sendlen = len;
    while(sendlen> 0){
        int rflag = send(_fd,pbuff,sendlen,0);
        if(rflag == -1 && EINTR == errno){
            continue;
        }else if(rflag == -1 ||rflag == 0){
            return len- sendlen;
        }
        sendlen -= rflag;
        pbuff += rflag;
    }
    return len -sendlen;
}
Packet SocketIO::recvPacket(){
    uint64_t ts;
    int ret = 0;
    while(ret <8){
        ret = recv(_fd,(char*)&ts,8,MSG_PEEK);
    }
    int type;
    int len ; 
    recvn((char *)&type,4);
    if(type > 40){
        char buff[4096]={0};
        recvn(buff,4096);
        return Packet("");
    }
    recvn((char *)&len,4);
    cout<<"type : "<<type<< " len: "<<len<<endl;
    char buff[4096]={0};
    recvn(buff,len);
    return Packet(type,len,buff);
}

